package logic

import (
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"pharymacy-management-system/dao/mysql"
	"pharymacy-management-system/models"
	"pharymacy-management-system/network"
	"pharymacy-management-system/pkg/snowflake"
)

func AddStockOperate(c *gin.Context) {
	operateName := c.Param("operateName")
	operate, err := mysql.SelectOperateByName(operateName)
	if err != nil {
		zap.L().Error("mysql.SelectOperateByName(operateName) failed", zap.Error(err))
		network.ResponseError(c, network.CodeServerBusy)
		return
	}
	if operate != nil {
		zap.L().Error("stock operate already exists", zap.String("operateName", operateName))
		network.ResponseErrorWithMsg(c, network.CodeInvalidParam, "操作已存在")
		return
	}
	err = mysql.InsertStockOperate(operateName)
	if err != nil {
		zap.L().Error("mysql.AddStockOperate(operateName) failed", zap.Error(err), zap.String("operateName", operateName))
		network.ResponseError(c, network.CodeServerBusy)
		return
	}
	network.ResponseSuccess(c, nil)
}

func GetAllStockOperate(c *gin.Context) {
	operates, err := mysql.SelectAllStockOperate()
	if err != nil {
		zap.L().Error("mysql.SelectAllStockOperate() failed", zap.Error(err))
		network.ResponseError(c, network.CodeServerBusy)
		return
	}
	data := map[string]interface{}{}
	data["operateList"] = operates
	network.ResponseSuccess(c, data)
}

func UpdateStockOperate(c *gin.Context) {
	var operate models.ParamOperate
	err := c.ShouldBindJSON(&operate)
	if err != nil {
		zap.L().Error("c.ShouldBindJSON(&operate) failed", zap.Error(err))
		network.ResponseError(c, network.CodeInvalidParam)
		return
	}
	operate2, err := mysql.SelectOperateByName(operate.OperateName)
	if err != nil {
		zap.L().Error("mysql.SelectOperateByName(operateName) failed", zap.Error(err))
		network.ResponseError(c, network.CodeServerBusy)
		return
	}
	if operate2 != nil {
		zap.L().Error("stock operate already exists", zap.String("operateName", operate.OperateName))
		network.ResponseErrorWithMsg(c, network.CodeInvalidParam, "操作已存在")
		return
	}
	err = mysql.UpdateStockOperateByID(&operate)
	if err != nil {
		zap.L().Error("mysql.UpdateStockOperateByID(&operate) failed", zap.Error(err))
		network.ResponseError(c, network.CodeServerBusy)
		return
	}
	network.ResponseSuccess(c, nil)
}

func AddStock(c *gin.Context) {
	var paramStock models.ParamStock
	err := c.ShouldBindJSON(&paramStock)
	if err != nil {
		zap.L().Error("c.ShouldBindJSON(&paramStock) failed", zap.Error(err))
		network.ResponseError(c, network.CodeInvalidParam)
		return
	}

	userId, err := network.GetCurrentUser(c)
	if err != nil {
		zap.L().Error("network.GetCurrentUser(c) failed", zap.Error(err))
		network.ResponseError(c, network.CodeInvalidAuth)
		return
	}

	stockID := snowflake.GenID()
	stock := &models.Stock{
		StockID: stockID,
		DrugID:  paramStock.DrugID,
		Number:  paramStock.Number,
	}

	stockHistory := &models.StockHistory{
		StockID:   stockID,
		DrugID:    paramStock.DrugID,
		OperateID: paramStock.OperateID,
		Number:    paramStock.Number,
		UserID:    userId,
	}

	err = mysql.CreateStock(stock, stockHistory)
	if err != nil {
		zap.L().Error("mysql.CreateStock(stock, stockHistory) failed", zap.Error(err))
		network.ResponseError(c, network.CodeServerBusy)
		return
	}
	network.ResponseSuccess(c, nil)
}

func GetAllStock(c *gin.Context) {
	stockList, err := mysql.SelectAllStock()
	if err != nil {
		zap.L().Error("mysql.GetAllStock() failed", zap.Error(err))
		network.ResponseError(c, network.CodeServerBusy)
		return
	}
	data := map[string]interface{}{}
	data["stockList"] = stockList
	network.ResponseSuccess(c, data)
}

func UpdateStock(c *gin.Context) {
	var paramStock models.ParamStock
	err := c.ShouldBindJSON(&paramStock)
	if err != nil {
		zap.L().Error("c.ShouldBindJSON(&paramStock) failed", zap.Error(err))
		network.ResponseError(c, network.CodeInvalidParam)
		return
	}

	userId, err := network.GetCurrentUser(c)
	if err != nil {
		zap.L().Error("network.GetCurrentUser(c) failed", zap.Error(err))
		network.ResponseError(c, network.CodeInvalidAuth)
		return
	}

	stock := &models.Stock{
		StockID: paramStock.StockID,
		DrugID:  paramStock.DrugID,
		Number:  paramStock.Number,
	}

	stockHistory := &models.StockHistory{
		StockID:   paramStock.StockID,
		DrugID:    paramStock.DrugID,
		OperateID: paramStock.OperateID,
		Number:    paramStock.Number,
		UserID:    userId,
	}

	err = mysql.UpdateStockAndHistory(stock, stockHistory)
	if err != nil {
		zap.L().Error("mysql.UpdateStockAndHistory(stock, stockHistory) failed", zap.Error(err))
		network.ResponseError(c, network.CodeServerBusy)
		return
	}

	network.ResponseSuccess(c, nil)
}

func GetAllStockHistory(c *gin.Context) {
	stockHistoryList, err := mysql.GetAllStockHistory()

	if err != nil {
		zap.L().Error("mysql.GetAllStockHistory() failed", zap.Error(err))
		network.ResponseError(c, network.CodeServerBusy)
		return
	}

	data := map[string]interface{}{}
	data["stockHistoryList"] = stockHistoryList
	network.ResponseSuccess(c, data)
}

func GetStockHistoryByStockId(c *gin.Context) {
	stockId := c.Param("stockId")
	stockHistoryList, err := mysql.GetStockHistoryByStockId(stockId)

	if err != nil {
		zap.L().Error("mysql.GetStockHistoryByStockId(stockId) failed", zap.Error(err))
		network.ResponseError(c, network.CodeServerBusy)
		return
	}

	data := map[string]interface{}{}
	data["stockHistoryList"] = stockHistoryList
	network.ResponseSuccess(c, data)
}
